#include "downloadwidget.h"
#include "ui_downloadwidget.h"

DownloadWidget::DownloadWidget(QWebEngineDownloadRequest *download, QWidget *parent) :
    QFrame(parent),
    m_download(download),
    m_timeAdded(QTime::currentTime()),
    ui(new Ui::DownloadWidget)
{
    ui->setupUi(this);

    this->ui->m_dstName->setText(QFileInfo(m_download->downloadFileName()).fileName());
    this->ui->m_srcUrl->setText(m_download->url().toDisplayString());

    connect(this->ui->m_cancelButton, &QPushButton::clicked,
            [this](bool) {
        if (m_download->state() == QWebEngineDownloadRequest::DownloadInProgress)
            m_download->cancel();
        else
            emit removeClicked(this);
    });

    connect(m_download, &QWebEngineDownloadRequest::receivedBytesChanged,
            this, &DownloadWidget::updateWidget);

    connect(m_download, &QWebEngineDownloadRequest::stateChanged,
            this, &DownloadWidget::updateWidget);

    updateWidget();
}

DownloadWidget::~DownloadWidget()
{
    delete ui;
}

void DownloadWidget::updateWidget()
{
    qreal totalBytes = m_download->totalBytes();
    qreal receivedBytes = m_download->receivedBytes();
    qreal bytesPerSecond = receivedBytes / m_timeAdded.currentTime().second();

    auto state = m_download->state();
    switch (state) {
    case QWebEngineDownloadRequest::DownloadRequested:
        Q_UNREACHABLE();
        break;
    case QWebEngineDownloadRequest::DownloadInProgress:
        if (totalBytes >= 0) {
            this->ui->m_progressBar->setValue(qRound(100 * receivedBytes / totalBytes));
            this->ui->m_progressBar->setDisabled(false);
            this->ui->m_progressBar->setFormat(
                tr("%p% - %1 of %2 downloaded - %3/s")
                .arg(withUnit(receivedBytes))
                .arg(withUnit(totalBytes))
                .arg(withUnit(bytesPerSecond)));
        } else {
            this->ui->m_progressBar->setValue(0);
            this->ui->m_progressBar->setDisabled(false);
            this->ui->m_progressBar->setFormat(
                tr("unknown size - %1 downloaded - %2/s")
                .arg(withUnit(receivedBytes))
                .arg(withUnit(bytesPerSecond)));
        }
        break;
    case QWebEngineDownloadRequest::DownloadCompleted:
        this->ui->m_progressBar->setValue(100);
        this->ui->m_progressBar->setDisabled(true);
        this->ui->m_progressBar->setFormat(
            tr("completed - %1 downloaded - %2/s")
            .arg(withUnit(receivedBytes))
            .arg(withUnit(bytesPerSecond)));
        break;
    case QWebEngineDownloadRequest::DownloadCancelled:
        this->ui->m_progressBar->setValue(0);
        this->ui->m_progressBar->setDisabled(true);
        this->ui->m_progressBar->setFormat(
            tr("cancelled - %1 downloaded - %2/s")
            .arg(withUnit(receivedBytes))
            .arg(withUnit(bytesPerSecond)));
        break;
    case QWebEngineDownloadRequest::DownloadInterrupted:
        this->ui->m_progressBar->setValue(0);
        this->ui->m_progressBar->setDisabled(true);
        this->ui->m_progressBar->setFormat(
            tr("interrupted: %1")
            .arg(m_download->interruptReasonString()));
        break;
    }

    if (state == QWebEngineDownloadRequest::DownloadInProgress) {
        static QIcon cancelIcon(QStringLiteral(":/app_resource/stop.png"));
        this->ui->m_cancelButton->setIcon(cancelIcon);
        this->ui->m_cancelButton->setToolTip(tr("Stop downloading"));
    } else {
        static QIcon removeIcon(QStringLiteral(":/app_resource/close.png"));
        this->ui->m_cancelButton->setIcon(removeIcon);
        this->ui->m_cancelButton->setToolTip(tr("Remove from list"));
    }
}

inline QString DownloadWidget::withUnit(qreal bytes)
{
    if (bytes < (1 << 10))
           return tr("%L1 B").arg(bytes);
       else if (bytes < (1 << 20))
           return tr("%L1 KiB").arg(bytes / (1 << 10), 0, 'f', 2);
       else if (bytes < (1 << 30))
           return tr("%L1 MiB").arg(bytes / (1 << 20), 0, 'f', 2);
       else
           return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
}

void DownloadWidget::on_pushButton_clicked()
{
    QDesktopServices::openUrl(QUrl("file:" + m_download->downloadDirectory(), QUrl::TolerantMode));
}

